const OK = 200;
const ERROR = 400;
$(document).ready(function () {
    $(this).initPlugin();
    if ($.support.pjax) {
        let pjaxContainer = '#pjax-container';
        $(document).pjax('a:not(.nop, [target="_blank"])', pjaxContainer, {
            timeout: 3000
        }).on('pjax:send', function () {
            NProgress.start();
        }).on('pjax:complete', function () {
            NProgress.done();
        }).on('pjax:end', function (e) {
            $(this).initPlugin();
        }).on('pjax:beforeReplace', function () {
            $(this).destroyPlugin();
        });
        $(document).on('submit', 'form[data-pjax]', function (e) {
            let $q = $('#input-search-text'),
                q = $.trim($q.val());
            if (q === '') {
                $q.val('').focus();
                return false;
            }
            $.pjax.submit(e, pjaxContainer)
        });
    }
    var clipboard = new ClipboardJS('.btn-copy');
    clipboard.on('success', function (e) {
        let text = e.trigger.innerHTML;
        e.trigger.innerHTML = '已复制';
        setTimeout(function () {
            e.trigger.innerHTML = text;
        }, 3000);
    });
    $(document).on('click', '.btn-copy', function (e) {
        e.preventDefault();
    });
    $(document).on('click', '.btn-clear-content', function (e) {
        e.preventDefault();
        let target = $(this).data('target');
        if (!target) {
            return;
        }
        let $target = $(target);
        if ($target.is('input') || $target.is('textarea')) {
            $target.val('');
        }
    });
    $(document).on('touchend click', 'a[data-pron]', function (e) {
        e.preventDefault();
        if (typeof (url) === 'undefined') {
            return;
        }
        let source = url + $(this).data('pron');
        media.audio.play(source);
    });
    $(document).on('click', '.captcha-refresh', function (e) {
        e.preventDefault();
        util.captcha.refresh();
    });
    $(document).on("click", "[data-dropdown]", function (e) {
        e.preventDefault();
        e.stopPropagation();
        $($(this).data('dropdown')).show().find('[role="menu"]').attr({
            'aria-expanded': true,
            'aria-hidden': false
        });
    });
    $(document).on("click", "body", function (e) {
        $('[data-dropdown]').each(function () {
            $($(this).data('dropdown')).hide().find('[role="menu"]').attr({
                'aria-expanded': false,
                'aria-hidden': true
            });
        });
    });
    $(document).on("click", "[data-toggle=collapse]", function (e) {
        e.preventDefault();
        var $this = $(this);
        var collapse = $this.attr('href') ? $this.attr('href') : $this.data('target');
        if (!collapse) {
            return;
        }
        var speed = $this.data('speed') ? $this.data('speed') : '';
        $(collapse).slideToggle(speed);
        if ($this.hasClass('dropright') || $this.hasClass('dropdown')) {
            if ($this.hasClass('dropright')) {
                $this.removeClass('dropright').addClass('dropdown');
            } else {
                $this.removeClass('dropdown').addClass('dropright');
            }
        }
    });
    $(document).on("keydown", "[contenteditable]", function (e) {
        var $this = $(this);
        var maxlength = $this.attr('maxlength');
        if (maxlength !== undefined) {
            maxlength = parseInt(maxlength);
            if ($this.text().length === maxlength && e.keyCode != 8) {
                e.preventDefault();
            }
        }
    });
    $(document).on('click', '.js-download', function (e) {
        e.preventDefault();
        var $this = $(this);
        var type = $this.data('type');
        var name = $this.data('name');
        var filename = $this.data('filename');
        var options = {
            type: type,
            params: {
                name: name,
                filename: filename
            }
        };
        util.download.file(options);
    });
    $(document).on('click', '.js-print', function (e) {
        e.preventDefault();
        var $this = $(this);
        var printable = $this.data('printable') ? $this.data('printable') : '.printable';
        var options = {
            noPrintSelector: '[data-no-print]',
            append: '<div class="print-date">打印时间：' + new Date().toLocaleString() + '</div>'
        };
        $(printable).print(options);
    });
    $(document).on('click', '.js-save-as-image', function (e) {
        e.preventDefault();
        var $this = $(this);
        var save = function () {
            var text = $this.html();
            $this.html('正在生成图片...');
            var filename = $this.data('filename') ? $this.data('filename') : '下载';
            var scale = $this.data('scale') ? $this.data('scale') : 2;
            scale = parseInt(scale);
            scale = Math.min(scale, 2);
            scale = Math.max(scale, 1);
            var $imageContainer = $this.data('screenshot') ? $($this.data('screenshot')) : $('.screenshotable');
            var width = $imageContainer.outerWidth(),
                height = $imageContainer.outerHeight();
            var canvas = document.createElement("canvas");
            canvas.width = width * scale;
            canvas.height = height * scale;
            canvas.style.width = width + "px";
            canvas.style.height = height + "px";
            var context = canvas.getContext("2d");
            context.scale(scale, scale);
            var rect = $imageContainer.get(0).getBoundingClientRect();
            context.translate(-rect.left, -rect.top);
            var offset = $imageContainer.offset();
            html2canvas($imageContainer.get(0), {
                canvas: canvas,
                scale: scale,
                backgroundColor: "transparent",
                x: offset.left,
                y: offset.top,
                useCORS: true
            }).then(function (canvas) {
                util.download.image(canvas, {
                    filename: filename
                });
                $this.html(text);
            });
        }
        var beforeSave = $this.data('beforeSave');
        if (beforeSave && window.clickHandler[beforeSave] && typeof window.clickHandler[beforeSave] === 'function') {
            window.clickHandler[beforeSave]($this, function () {
                save();
            });
        } else {
            save();
        }
    });
    $(document).on("click", '.btn-share-to-wechat', function (e) {
        e.preventDefault();
        if (this.modal) {
            this.modal.open();
            return;
        }
        var options = {
            footer: true,
            closeMethods: ['escape'],
            cssClass: ['modal-wechat-qrcode'],
            beforeOpen: function () {
                var $pageQRcodeContainer = $('#page-qrcode-container');
                if ($pageQRcodeContainer.data('exists') == 1) {
                    return;
                }
                var wechatUrl = $('#page-canonical-url').val() + '?ref=qrcode&source=wechat';
                var _options = {
                    text: wechatUrl,
                    width: 240,
                    height: 240,
                    border: 10
                };
                var icon = $('#image-url').length > 0 ? $('#image-url').val() : null;
                if (icon) {
                    $.extend(_options, {
                        iconSrc: icon,
                        iconRadius: 8,
                        iconBorderWidth: 6,
                        iconBorderColor: '#fff'
                    });
                }
                new QRCode($pageQRcodeContainer[0], _options);
                $pageQRcodeContainer.data('exists', 1);
            },
            onOpen: function () {
                $('.tingle-modal-box').attr('role', 'dialog');
            },
            footerButtons: [{
                label: '关闭',
                cssClass: 'btn btn-primary btn-lg',
                callback: function () {
                    this.close();
                }
            }]
        };
        var content = $('#share-to-wechat-template').html();
        this.modal = (new modal(content, options)).open();
    });
});
$.fn.destroyPlugin = function () {
    window.loaded = null;
    window.resize = null;
    window.onresize = null;
    if ($.fn.datepicker) {
        $('.datepicker').datepicker('destroy');
    }
    if (window.unloaded && typeof window.unloaded === 'function') {
        window.unloaded();
    }
}
$.fn.initPlugin = function () {
    if (styles !== undefined) {
        styles = styles.map(function (style) {
            return STATIC_URL + style;
        });
        $('.async-page-style').remove();
        (function (styles) {
            if (typeof styles === 'string') {
                loader.style(styles);
            } else {
                for (let i in styles) {
                    loader.style(styles[i]);
                }
            }
        })(styles);
    }
    if (typeof scripts !== undefined && scripts.length > 0) {
        scripts = scripts.map(function (script) {
            return STATIC_URL + script;
        });
        (function (scripts) {
            loader.scripts(scripts, function () {
                $(this).executePlugin();
            });
        })(scripts);
    } else {
        $(this).executePlugin();
    }
}
$.fn.executePlugin = function () {
    $(this).imageLazyload().initArticleHeader().initTooltip().initSticky().initUploader().initRangeSlider().initDatePicker().initDoubleRainbowPicker().initColorPicker().initCodeMirror().codeHighlight().searchResultHighlight().initEventHandler();
    if (window.loaded && typeof window.loaded === 'function') {
        window.loaded();
    }
    if (window.resize && typeof window.resize === 'function') {
        window.onresize = function () {
            window.resize();
        }
    }
}
$.fn.imageLazyload = function () {
    const loadImage = image => {
        let src = image.getAttribute('data-src');
        let srcset = src.replace(/(\.[0-9a-z]+)$/i, '@2x$1');
        src = STATIC_URL + src;
        srcset = STATIC_URL + srcset;
        util.image.fetch(src).then(() => {
            image.src = src;
        }).then(() => {
            util.image.fetch(srcset).then(() => {
                image.setAttribute('srcset', srcset + ' 2x');
            });
        });
    };
    const lazyload = image => {
        const io = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    loadImage(entry.target);
                    observer.disconnect();
                }
            });
        });
        io.observe(image);
    };
    let images = document.querySelectorAll('[data-src]');
    if ('IntersectionObserver' in window) {
        images.forEach(lazyload);
    } else {
        images.forEach(image => {
            loadImage(image);
        });
    }
    return this;
};
$.fn.initEventHandler = function () {
    $(document).off("click", "[data-click-handler], [data-click-emitter]").on("click", "[data-click-handler], [data-click-emitter]", function (e) {
        e.preventDefault();
        var $this = $(this);
        if ($this.data('spp') !== undefined) {
            e.stopPropagation();
        }
        if (!window.clickHandler) {
            return;
        }
        var handler = $this.data('click-handler');
        if (!handler) {
            if (typeof window.clickHandler === 'function') {
                window.clickHandler($(e.target));
            }
        } else {
            if (window.clickHandler[handler] && typeof window.clickHandler[handler] === 'function') {
                window.clickHandler[handler]($(e.target));
            }
        }
    });
    $(document).on("change", '[data-change-handler]', function (e) {
        e.preventDefault();
        e.stopImmediatePropagation();
        if (!window.changeHandler) {
            return;
        }
        var $this = $(e.target);
        var handler = $(this).data('change-handler');
        if (!handler) {
            if (typeof window.changeHandler === 'function') {
                window.changeHandler($this);
            }
        } else {
            if (window.changeHandler[handler] && typeof window.changeHandler[handler] === 'function') {
                window.changeHandler[handler]($this);
            }
        }
    });
    $(document).on("keyup", "[data-keyup-trigger]", function (e) {
        if (e.which != 13) {
            return;
        }
        var $this = $(this);
        var trigger = $this.data('keyup-trigger');
        if (!trigger) {
            return;
        }
        $this.blur();
        $(trigger).trigger('click');
    });
    return this;
};
$.fn.initSticky = function () {
    if ($.fn.stick_in_parent && $('.sticker').length > 0) {
        var $this, offsetTop = 16;
        $('.sticker').each(function () {
            $this = $(this);
            if ($this.data('offset-top') !== undefined) {
                offsetTop = $this.data('offset-top');
            }
            $this.stick_in_parent({
                offset_top: offsetTop
            }).on("sticky_kit:stick", function (e) {
                if (typeof _sticky === 'object' && typeof _sticky.onstick === 'function') {
                    _sticky.onstick(e);
                }
            }).on("sticky_kit:unstick", function (e) {
                if (typeof _sticky === 'object' && typeof _sticky.onunstick === 'function') {
                    _sticky.onunstick(e);
                }
            });
        });
    }
    return this;
};
$.fn.initUploader = function () {
    if ($.fn.dmUploader && $('.imageupload').length > 0) {
        $('.imageupload').each(function () {
            let options = {};
            if (typeof _options !== 'undefined') {
                let key = $(this).data('key');
                key = key ? key : 'default';
                if (_options[key]) {
                    $.extend(options, _options[key]);
                }
            }
            let uploaderIns = (new uploader('.imageupload')).init(options);
            $(this).data('uploader', uploaderIns);
        });
    }
    return this;
};
$.fn.initRangeSlider = function () {
    $range = $('input[type="range"]');
    if ($range.length === 0) {
        return this;
    }
    if ($.fn.rangeslider) {
        $range.rangeslider('destroy').each(function () {
            var $this = $(this);
            var key = $this.data('key') ? $this.data('key') : 'default';
            var $target = $this.data('target') ? $($this.data('target')) : null;
            var options = {
                polyfill: false,
                rangeClass: 'rangeslider',
                disabledClass: 'rangeslider-disabled',
                horizontalClass: 'rangeslider-horizontal',
                verticalClass: 'rangeslider-vertical',
                fillClass: 'rangeslider-fill',
                handleClass: 'rangeslider-handle',
                onInit: function () {
                    if ($target !== null) {
                        $target.html($this.val());
                    }
                },
                onSlide: function (position, value) {
                    if ($target !== null) {
                        $target.html(value);
                    }
                },
                onSlideEnd: function (position, value) {
                    $this.attr('aria-valuenow', value);
                }
            };
            if (typeof (_rangeSliderOptions) === 'object' && _rangeSliderOptions[key] !== undefined) {
                $.extend(options, _rangeSliderOptions[key]);
            }
            $this.rangeslider(options);
        });
    }
    return this;
};
$.fn.initDatePicker = function () {
    if ($.fn.datepicker && $('.datepicker').length > 0) {
        let options = {
            language: 'zh-CN',
            autoHide: true,
            format: 'yyyy-mm-dd'
        };
        $('.datepicker').each(function () {
            $(this).datepicker(options);
        });
    }
    return this;
};
$.fn.initDoubleRainbowPicker = function () {
    if (typeof (DoubleRainbow) === 'function' && $('.double-rainbow-picker').length > 0) {
        $('.double-rainbow-picker').each(function () {
            new DoubleRainbow(this).init();
        });
    }
    return this;
};
$.fn.initColorPicker = function () {
    $('.sp-container').remove();
    if ($.fn.spectrum && $('.color-picker').length > 0) {
        $('.color-picker').each(function () {
            var $this = $(this);
            var key = $this.data('key') ? $this.data('key') : 'default';
            var palette = [
                ["rgb(0, 0, 0)", "rgb(67, 67, 67)", "rgb(102, 102, 102)", "rgb(153, 153, 153)", "rgb(183, 183, 183)", "rgb(204, 204, 204)", "rgb(217, 217, 217)", "rgb(239, 239, 239)", "rgb(243, 243, 243)", "rgb(255, 255, 255)"],
                ["rgb(152, 0, 0)", "rgb(255, 0, 0)", "rgb(255, 153, 0)", "rgb(255, 255, 0)", "rgb(0, 255, 0)", "rgb(0, 255, 255)", "rgb(74, 134, 232)", "rgb(0, 0, 255)", "rgb(153, 0, 255)", "rgb(255, 0, 255)"],
                ["rgb(230, 184, 175)", "rgb(244, 204, 204)", "rgb(252, 229, 205)", "rgb(255, 242, 204)", "rgb(217, 234, 211)", "rgb(208, 224, 227)", "rgb(201, 218, 248)", "rgb(207, 226, 243)", "rgb(217, 210, 233)", "rgb(234, 209, 220)", "rgb(221, 126, 107)", "rgb(234, 153, 153)", "rgb(249, 203, 156)", "rgb(255, 229, 153)", "rgb(182, 215, 168)", "rgb(162, 196, 201)", "rgb(164, 194, 244)", "rgb(159, 197, 232)", "rgb(180, 167, 214)", "rgb(213, 166, 189)", "rgb(204, 65, 37)", "rgb(224, 102, 102)", "rgb(246, 178, 107)", "rgb(255, 217, 102)", "rgb(147, 196, 125)", "rgb(118, 165, 175)", "rgb(109, 158, 235)", "rgb(111, 168, 220)", "rgb(142, 124, 195)", "rgb(194, 123, 160)", "rgb(166, 28, 0)", "rgb(204, 0, 0)", "rgb(230, 145, 56)", "rgb(241, 194, 50)", "rgb(106, 168, 79)", "rgb(69, 129, 142)", "rgb(60, 120, 216)", "rgb(61, 133, 198)", "rgb(103, 78, 167)", "rgb(166, 77, 121)", "rgb(133, 32, 12)", "rgb(153, 0, 0)", "rgb(180, 95, 6)", "rgb(191, 144, 0)", "rgb(56, 118, 29)", "rgb(19, 79, 92)", "rgb(17, 85, 204)", "rgb(11, 83, 148)", "rgb(53, 28, 117)", "rgb(116, 27, 71)", "rgb(91, 15, 0)", "rgb(102, 0, 0)", "rgb(120, 63, 4)", "rgb(127, 96, 0)", "rgb(39, 78, 19)", "rgb(12, 52, 61)", "rgb(28, 69, 135)", "rgb(7, 55, 99)", "rgb(32, 18, 77)", "rgb(76, 17, 48)"]
            ];
            var options = {
                color: 'black',
                preferredFormat: 'hex',
                showInput: true,
                showPalette: true,
                showAlpha: true,
                showInput: true,
                showButtons: true,
                showSelectionPalette: true,
                hideAfterPaletteSelect: true,
                palette: palette
            };
            if (typeof (_colorPickerOptions) === 'object' && _colorPickerOptions[key] !== undefined) {
                $.extend(options, _colorPickerOptions[key]);
            }
            $this.spectrum(options)
        });
    }
    return this;
};
$.fn.initCodeMirror = function () {
    if (typeof (CodeMirror) !== "undefined") {
        $('.CodeMirror').remove();
        $('.codemirror-control').each(function () {
            var $this = $(this);
            var bindto = $this.data('bindto');
            var copyBindto = $this.data('copyBindto');
            copyBindto = copyBindto === undefined ? '.btn-copy-code' : copyBindto;
            var clearBindto = $this.data('clearBindto');
            clearBindto = clearBindto === undefined ? '.btn-clear-code' : clearBindto;
            var config = {
                theme: "default",
                lineNumbers: true,
                cursorHeight: .85,
                matchBrackets: true,
                autoCloseBrackets: true,
                indentUnit: 4,
                htmlMode: true,
                foldGutter: true,
                gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "customergutter"]
            };
            if ($this.data('mode')) {
                $.extend(config, {
                    mode: $this.data('mode')
                });
            }
            if ($this.data('line-numbers') != null) {
                $.extend(config, {
                    lineNumbers: $this.data('line-numbers') == '0' ? false : true
                });
            }
            if ($this.data('gutters') == '0') {
                $.extend(config, {
                    gutters: []
                });
            }
            if ($this.data('disable-enter-key')) {
                $.extend(config, {
                    extraKeys: {
                        'Enter': function () {
                            return false;
                        }
                    }
                });
            }
            if ($this.data('line-wrapping')) {
                $.extend(config, {
                    lineWrapping: true
                });
            }
            if ($this.is('[readonly]')) {
                $.extend(config, {
                    readOnly: 'nocursor'
                });
            }
            var myeditor = CodeMirror.fromTextArea(this, config);
            $this.data('cm-editor', myeditor);
            var changeHandler = $this.data('change-handler');
            myeditor.on('change', function (cm, change) {
                var value = cm.getValue();
                $(copyBindto).prop('disabled', value === '');
                if (changeHandler !== undefined) {
                    $this.val(value).trigger('change');
                }
            });
            if (bindto && $(bindto).length > 0) {
                $(bindto).data('cm-editor', myeditor);
            }
            $(document).off('click', clearBindto).on('click', clearBindto, function () {
                myeditor.setValue("");
                myeditor.clearHistory();
            });
            if (typeof (ClipboardJS) !== 'undefined') {
                new ClipboardJS(copyBindto, {
                    text: function (trigger) {
                        return myeditor.getValue();
                    }
                }).on('success', function (e) {
                    myeditor.execCommand('selectAll');
                    let text = e.trigger.innerHTML;
                    e.trigger.innerHTML = '已复制';
                    setTimeout(function () {
                        e.trigger.innerHTML = text;
                    }, 3000);
                });
            }
        });
    }
    return this;
};
$.fn.initTooltip = function () {
    if (typeof (Tooltip) !== 'undefined' && $('[data-toggle="tooltip"]').length > 0) {
        $('[data-toggle="tooltip"]').each(function () {
            var $this = $(this);
            var options = {
                placement: $this.data('placement') ? $this.data('placement') : 'bottom',
                title: $this.data('title'),
                html: true
            }
            new Tooltip($this, options);
        });
    }
    return this;
};
$.fn.initArticleHeader = function () {
    if ($('.headable').length > 0) {
        var slugs = [];
        $('.headable').find('h1,h2,h3,h4').each(function (index) {
            var $this = $(this);
            var idText = $this.attr('id');
            if (!idText) {
                idText = util.string.slugify($this.text());
                if (idText === '') {
                    idText = 'heading-' + (index + 1);
                }
                if ($.inArray(idText, slugs) !== -1) {
                    idText = idText + '-' + (index + 1);
                }
                slugs.push(idText);
                $this.attr({
                    id: idText
                });
            }
            $this.prepend('<a href="#' + idText + '" class="anchor"><span></span></a>');
        });
    }
    return this;
};
$.fn.codeHighlight = function () {
    Prism.highlightAll();
    return this;
};
$.fn.searchResultHighlight = function () {
    if ($.fn.highlight) {
        let query = $('.query-text').val();
        $('.highlightable').highlight(query);
    }
    return this;
};